package com.bianmin.Controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import com.bianmin.Data.Result;
import com.bianmin.Data.ResultCode;
import com.bianmin.Mapper.OrderMapper;
import com.bianmin.Mapper.UserMapper;
import com.bianmin.Mapper.UtilMapper;
import com.bianmin.Model.Order;
import com.bianmin.coomen.Util;
import com.bianmin.coomen.payUtil.WechatPayRequest;
import com.bianmin.coomen.payUtil.WxPayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;

import java.util.Random;
import cn.hutool.core.util.IdUtil;


import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

//下单接口
@RestController
@RequestMapping("api/wxPay")
public class WxPayController {

    //https://blog.csdn.net/T_2021_7_10/article/details/132276992

    @Resource
    private WxPayConfig wechatPayConfig;

    @Resource
    private WechatPayRequest wechatPayRequest;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UtilMapper utilMapper;

    /**
     * 预支付订单生成入口
     */
    @PostMapping("createOrder")
    public Result<Object> transactions(@RequestBody Map<String,Object> payParame) {
        //商品名称，价格。openid
        if (payParame.size() != 4) {
            return  Result.error(ResultCode.RC2001);
        }

        // 将Double转换为整数并乘以100
        Integer totalPrice = Integer.parseInt(payParame.get("totalPrice").toString());
        String goodsId = payParame.get("goodsId").toString();
        //获取商品名称
        String goodsName = utilMapper.selectGoodsById(goodsId).getName();
        //创建订单号
        String outTradeNo = "DD" + Util.randomString(6) + Util.currentTimesStamp();
        String userId = payParame.get("userId").toString();
        String openId = userMapper.queryOpenIdById(userId);
        //文章id
        String articleId = payParame.get("articleId").toString();


        // 统一参数封装
        Map<String, Object> params = new HashMap<>(10);
        // 1,appid：公众号或移动应用的唯一标识符。
        params.put("appid", wechatPayConfig.getAppId());
        // 2,mch_id：商户号，由微信支付分配。
        params.put("mchid", wechatPayConfig.getMerchantId());
      // 3.description body：商品描述。
        params.put("description", goodsName);
        // 4.out_trade_no：商户订单号，由商户自定义。
        params.put("out_trade_no", outTradeNo);
        // 5.notify_url：接收微信支付异步通知回调地址。
        params.put("notify_url", wechatPayConfig.getPayNotifyUrl());
        // 6.total_fee：订单总金额，单位为分。
        Map<String, Object> amountMap = new HashMap<>(4);
        // 金额单位为分
        amountMap.put("total", totalPrice);
        amountMap.put("currency", "CNY");
        params.put("amount", amountMap);

        // 7.openid：用户在商户appid下的唯一标识。
        Map<String, Object> payerMap = new HashMap<>(4);

        payerMap.put("openid", openId);
        params.put("payer", payerMap);

        String paramsStr = JSON.toJSONString(params);
        System.out.println("请求参数 ===> {}" + paramsStr);
        // 微信预支付下单接口路径
        String payUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
        // 获取支付 prepay_id参数
        String resStr = wechatPayRequest.wechatHttpOrderPost(payUrl, paramsStr);

        Map<String, Object> resMap = JSONObject.parseObject(resStr, new TypeReference<Map<String, Object>>() {
        });
        Object prepayId = resMap.get("prepay_id");

        // 得到当前系统时间搓
        String timeStamp = String.valueOf(Util.currentTimesStamp());
        // 获取随机字符
        String nonceStr = IdUtil.fastSimpleUUID();
        // 获取签名
        String paySign;
        try {
            StringBuilder sb = new StringBuilder();
            // 应用id
            sb.append(wechatPayConfig.getAppId()).append("\n");
            // 支付签名时间戳
            sb.append(timeStamp).append("\n");
            // 随机字符串
            sb.append(nonceStr).append("\n");
            // 预支付交易会话ID  这个要注意 key = "prepay_id=xxxxxx"
            sb.append("prepay_id=").append(prepayId).append("\n");
            // 签名
            Signature sign = Signature.getInstance("SHA256withRSA");
            // 获取商户私钥并进行签名
            PrivateKey privateKey = wechatPayConfig.getPrivateKey(wechatPayConfig.getKeyPemPath());
            sign.initSign(privateKey);
            sign.update(sb.toString().getBytes(StandardCharsets.UTF_8));
            // 得到签名
            paySign = Base64.getEncoder().encodeToString(sign.sign());
        } catch (Exception e) {
            System.out.println("支付模块_生成交易签名失败！" + e);
            return Result.error(ResultCode.RC1001);
        }

        // 将签名时数据和签名一起返回前端用于前端吊起支付
        Map<String, Object> map = new HashMap<>();
        // 小程序id
        map.put("appId", wechatPayConfig.getAppId());
        // 时间戳
        map.put("timeStamp", timeStamp);
        // 随机字符串
        map.put("nonceStr", nonceStr);
        // 预支付交易会话ID
        map.put("package", "prepay_id=" + prepayId);
        // 签名方式
        map.put("signType", "RSA");
        // 签名
        map.put("paySign", paySign);

        Order order = new Order();
        order.setUserId(userId);
        order.setOrderNumber(outTradeNo);
        order.setArticleId(articleId);
        order.setGoodsId(Integer.valueOf(goodsId));
        order.setPrice(String.valueOf(totalPrice / 100));
        order.setCreateTime(Util.currentTimeString());
        order.setStatus(0);
        //创建业务订单
        orderMapper.insert(order);

        return Result.success(map);
    }



}
